/*
 * @Author: wuhao930406 1148547900@qq.com
 * @Date: 2023-05-26 11:32:31
 * @LastEditors: wuhao930406 1148547900@qq.com
 * @LastEditTime: 2023-09-06 14:39:53
 * @FilePath: /utools_tasks/utools_web/src/components/Weather/index.jsx
 * @Description:
 *
 * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
 */
import { Divider } from 'antd';
import './index.less';
import { useEffect, useMemo } from 'react';
import { useRequest } from 'ahooks';
import { useModel } from '@umijs/max';


function Weather() {
  const {
    initialState: { currentUser },
  } = useModel('@@initialState');


  const weather = useRequest(
    async () => {
      const url = new URL('https://restapi.amap.com/v3/ip');
      url.search = new URLSearchParams(GAODEKEY).toString();
      let ip = await fetch(url);
      ip = await ip.json();
      const params = { ...GAODEKEY, city: ip.adcode, extensions: 'base' };
      const urls = new URL('https://restapi.amap.com/v3/weather/weatherInfo');
      urls.search = new URLSearchParams(params).toString();

      let wea = await fetch(urls);
      wea = await wea.json();
      return {
        ...ip,
        ...(wea?.lives?.[0] ?? {}),
      };
    },
    {
      debounceWait: 300,
    },
  );

  const curweather = useMemo(() => {
    let it = weather?.data ?? { weather: '阴' };
    let keyarr = ['晴', '阴', '霾', '雾', '云', '雷', '雪', '雨'];
    let curkey = keyarr.filter((item) => it?.weather?.indexOf(item) !== -1)[0] ?? "weather";
    return curkey;
  }, [weather])

  useEffect(() => {
    const canvas = document.getElementById('weatherCanvas');
    const ctx = canvas.getContext('2d');
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    let animationFrameId;

    function clearCanvas() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
    }

    function drawSunnyBackground() {
      clearCanvas();
      // 光柱的配置
      const beams = [
        { startX: 5, startY: -20, width: canvas.width, height: 10, alpha: 0.3, angleA: 20, angleB: 30, currentAngle: 20, speed: 0.01 },
        { startX: 0, startY: 0, width: canvas.width, height: 10, alpha: 0.3, angleA: 40, angleB: 50, currentAngle: 40, speed: 0.008 },
        { startX: -20, startY: 5, width: canvas.width, height: 10, alpha: 0.3, angleA: 50, angleB: 70, currentAngle: 60, speed: 0.006 },
      ];
      function drawBeam(beam) {
        const radianAngle = beam.currentAngle * Math.PI / 180;
        const gradient = ctx.createRadialGradient(beam.startX, beam.startY, 0, beam.startX, beam.startY, Math.hypot(beam.width, beam.height));
        gradient.addColorStop(0, `rgba(255, 255, 0, ${beam.alpha})`);
        gradient.addColorStop(0.25, 'rgba(255, 255, 255, 0)');
        ctx.fillStyle = gradient;
        ctx.save();
        ctx.translate(beam.startX, beam.startY);
        ctx.rotate(radianAngle);
        ctx.translate(-beam.startX, -beam.startY);
        ctx.fillRect(beam.startX, beam.startY, beam.width, beam.height);
        ctx.restore();
      }

      function animateSunny() {
        clearCanvas();

        beams.forEach(beam => {
          if (beam.currentAngle >= beam.angleB) {
            beam.speed = -Math.abs(beam.speed); // 到达B点反向运动
          } else if (beam.currentAngle <= beam.angleA) {
            beam.speed = Math.abs(beam.speed); // 到达A点正向运动
          }
          beam.currentAngle += beam.speed;
          drawBeam(beam);
        });

        animationFrameId = requestAnimationFrame(animateSunny);
      }
      animateSunny();
    }

    function drawStormBackground() {
      clearCanvas();
      const lightningStrikeOffset = 2;
      const lightningStrikeLength = 100;
      const lightningBoltLength = 5;
      const lightningThickness = 4;
      const canvasWidth = canvas.width;

      const createVector = function (x, y) { return { x, y } }

      const getRandomFloat = function (min, max) {
        const random = Math.random() * (max - min + 1) + min;
        return random;
      }

      const getRandomInteger = function (min, max) {
        return Math.floor(getRandomFloat(min, max));
      }

      const line = function (start, end, thickness, opacity) {
        ctx.beginPath();
        ctx.moveTo(start.x, start.y);
        ctx.lineTo(end.x, end.y);
        ctx.lineWidth = thickness;
        ctx.strokeStyle = currentUser.theme === 'light' ? '#ddd' : `rgba(255, 255, 255, ${opacity})`;
        ctx.shadowBlur = 20;
        ctx.shadowColor = "#bd9df2";
        ctx.stroke();
        ctx.closePath();
      }

      class Lightning {
        constructor(x1, y1, x2, y2, thickness, opacity) {
          this.start = createVector(x1, y1);
          this.end = createVector(x2, y2);
          this.thickness = thickness;
          this.opacity = opacity;
        }
        draw() {
          return line(this.start, this.end, this.thickness, this.opacity);
        }
      }

      const interval = 3000;
      // const lightningStrikeOffset = 5;
      // const lightningStrikeLength = 100;
      // const lightningBoltLength = Math.random() * 10;
      // const lightningThickness = 4;
      let lightning = [];


      const createLightning = function () {
        lightning = [];
        let lightningX1 = getRandomInteger(2, canvasWidth - 2);
        let lightningX2 = getRandomInteger(lightningX1 - lightningStrikeOffset, lightningX1 + lightningStrikeOffset);
        lightning[0] = new Lightning(lightningX1, 0, lightningX2, lightningBoltLength, lightningThickness, 1);
        for (let l = 1; l < lightningStrikeLength; l++) {
          let lastBolt = lightning[l - 1];
          let lx1 = lastBolt.end.x;
          let lx2 = getRandomInteger(lx1 - lightningStrikeOffset, lx1 + lightningStrikeOffset);
          lightning.push(new Lightning(
            lx1,
            lastBolt.end.y,
            lx2,
            lastBolt.end.y + lightningBoltLength,
            lastBolt.thickness,
            lastBolt.opacity
          ));
        }
      }


      const setup = function () {
        createLightning();
        for (let i = 0; i < lightning.length; i++) {
          lightning[i].draw();
        }
      }

      const animate = function () {
        clearCanvas();

        for (let i = 0; i < lightning.length; i++) {
          lightning[i].opacity -= 0.01;
          lightning[i].thickness -= 0.05;
          if (lightning[i].thickness <= 2) {
            lightning[i].end.y -= 0.05;
          }
          lightning[i].draw();
        }

        requestAnimationFrame(animate);
      }

      setup();
      requestAnimationFrame(animate);
      setInterval(function () {
        createLightning();
      }, interval)
    }

    function drawRainyBackground() {
      clearCanvas();
      const raindrops = [];
      for (let i = 0; i < 20; i++) {
        raindrops.push({
          x: Math.random() * canvas.width,
          y: Math.random() * canvas.height,
          length: Math.random() * 20 + 10,
          speed: Math.random() * 5 + 2
        });
      }

      function drawRaindrop(x, y, length) {
        ctx.beginPath();
        ctx.moveTo(x, y);
        ctx.lineTo(x, y + length);
        ctx.strokeStyle = 'rgba(19, 194, 194,0.5)';
        ctx.lineWidth = 2;
        ctx.stroke();
      }

      function animateRainy() {
        clearCanvas();

        raindrops.forEach(raindrop => {
          raindrop.y += raindrop.speed;
          if (raindrop.y > canvas.height) {
            raindrop.y = -raindrop.length;
            raindrop.x = Math.random() * canvas.width;
          }
          drawRaindrop(raindrop.x, raindrop.y, raindrop.length);
        });

        animationFrameId = requestAnimationFrame(animateRainy);
      }

      animateRainy();
    }

    function drawSnowyBackground() {
      clearCanvas();
      const snowflakes = [];
      for (let i = 0; i < 100; i++) {
        snowflakes.push({
          x: Math.random() * canvas.width,
          y: Math.random() * canvas.height,
          radius: Math.random() * 4 + 1,
          speed: Math.random() * 1 + 0.5
        });
      }

      function drawSnowflake(x, y, radius) {
        ctx.beginPath();
        ctx.arc(x, y, radius, 0, Math.PI * 2);
        ctx.fillStyle = '#FFFFFF';
        ctx.fill();
      }

      function animateSnowy() {
        clearCanvas();

        snowflakes.forEach(snowflake => {
          snowflake.y += snowflake.speed;
          if (snowflake.y > canvas.height) {
            snowflake.y = -snowflake.radius;
            snowflake.x = Math.random() * canvas.width;
          }
          drawSnowflake(snowflake.x, snowflake.y, snowflake.radius);
        });

        animationFrameId = requestAnimationFrame(animateSnowy);
      }

      animateSnowy();
    }

    function drawPaperPlanesBackground() {
      clearCanvas();

      // 纸飞机的配置
      const paperPlanes = [];
      for (let i = 0; i < 5; i++) {
        paperPlanes.push({
          x: Math.random() * canvas.width,
          y: Math.random() * canvas.height / 2,
          size: Math.random() * 20 + 30,
          speed: Math.random() * 2 + 1,
          angle: Math.random() * Math.PI / 2
        });
      }

      function drawPaperPlane(x, y, size, angle) {
        ctx.save();
        ctx.translate(x, y);
        ctx.rotate(angle);
        ctx.beginPath();
        ctx.moveTo(0, 0);
        ctx.lineTo(-size, -size / 2);
        ctx.lineTo(-size / 2, 0);
        ctx.lineTo(-size, size / 2);
        ctx.closePath();
        ctx.fillStyle = "#999";
        ctx.fill();
        ctx.restore();
      }

      function animatePaperPlanes() {
        clearCanvas();
        paperPlanes.forEach(plane => {
          plane.x += plane.speed * Math.cos(plane.angle);
          plane.y += plane.speed * Math.sin(plane.angle);
          if (plane.x > canvas.width || plane.y > canvas.height || plane.y < 0) {
            plane.x = -plane.size;
            plane.y = Math.random() * canvas.height / 2;
          }
          drawPaperPlane(plane.x, plane.y, plane.size, plane.angle);
        });

        animationFrameId = requestAnimationFrame(animatePaperPlanes);
      }

      animatePaperPlanes();
    }

    function setWeather(weather) {
      if (animationFrameId) {
        cancelAnimationFrame(animationFrameId);
      }
      switch (weather) {
        case '晴':
          drawSunnyBackground();
          break;
        case '雷':
          drawStormBackground();
          break;
        case '雨':
          drawRainyBackground();
          break;
        case '雪':
          drawSnowyBackground();
          break;
        case '云':
          drawPaperPlanesBackground();
          break;
        case '阴':
          clearCanvas();
          break;
        default:
          clearCanvas();
      }
    }

    if (!curweather) {
      return null;
    }

    setWeather(curweather);
  }, [curweather, currentUser.theme])


  return (
    <canvas
      id="weatherCanvas"
      style={{
        position: "fixed",
        zIndex: 1,
        left: 0,
        top: 0,
        width: "100vw",
        height: "100vh",
        opacity: 0.8
      }} />
  );
}

export default Weather;
